package com.ksp.wke.kspa04;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class QueueController {

	/**
	 * 
		ArrayBlockingQueue ：一个由数组结构组成的有界阻塞队列。
		LinkedBlockingQueue ：一个由链表结构组成的有界阻塞队列。
		PriorityBlockingQueue ：一个支持优先级排序的无界阻塞队列。
		DelayQueue： 一个使用优先级队列实现的无界阻塞队列。
		SynchronousQueue： 一个不存储元素的阻塞队列。
		LinkedTransferQueue： 一个由链表结构组成的无界阻塞队列。
		LinkedBlockingDeque： 一个由链表结构组成的双向阻塞队列。
		
	 * 定义了 一个基于链接节点的无界线程安全队列
	 */
	private static ConcurrentLinkedQueue<OrderRequest> orderQueue = new ConcurrentLinkedQueue<OrderRequest>();

	/**
	 * 一个 int值可自动更新。看到的原子变量性质的描述 java.util.concurrent.atomic包装规范。
	 * 一个AtomicInteger是应用于诸如自动递增的计数器，
	 * 并不能作为一种 Integer置换。然而，这类扩展 Number允许统一访问的工具和实用程序处理数值基础班。
	 * 
	 * AtomicInteger这个类的存在是为了满足在高并发的情况下,原生的整型数值自增线程不安全的问题
	 * 
	 * 定义了产品总数，队列总数
	 */
    private static AtomicInteger totalprodocut;
    private static AtomicInteger totalQueSize;
    
    /**
     * Executors与ThreadPoolExecutor（阿里发布的 Java开发手册中强制线程池不允许使用 Executors 去创建）
		newSingleThreadExecutor
		创建一个单线程的线程池。这个线程池只有一个线程在工作
		
		newFixedThreadPool
		创建固定大小的线程池。每次提交一个任务就创建一个线程，直到线程达到线程池的最大大小。
		
		newCachedThreadPool
		创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程，
		那么就会回收部分空闲（60秒不执行任务）的线程，当任务数增加时，此线程池又可以智能的添加新线程来处理任务。
		此线程池不会对线程池大小做限制，线程池大小完全依赖于操作系统（或者说JVM）能够创建的最大线程大小。
     */
    private ExecutorService excutorService = Executors.newCachedThreadPool();
    
    /**
		重入锁（ReentrantLock）是一种递归无阻塞的同步机制。
     * 
     */
    public static ReentrantLock queueLock = new ReentrantLock(true);

    static {
        totalprodocut = new AtomicInteger(15);
        totalQueSize = new AtomicInteger(15);
    }

    @RequestMapping("/queque")
    public String queque(OrderRequest orderRequest) {
        try {
            // queueLock.lock();
            if (totalprodocut.get() < 1) {
                return "error";
            } else {
                if (orderQueue.size() < totalQueSize.get()) {
                     System.out.println(orderRequest.getGoodId()+" 增加到待处理队列成功:" + orderQueue.size());
                    orderQueue.add(orderRequest);
                } else {
                    return "error";
                }
            }
            if (!OrderDealThread.dealLock.isLocked()) {
                OrderDealThread dealQueue = new OrderDealThread(orderQueue);
                excutorService.execute(dealQueue);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "not done";
        } finally {
            // queueLock.unlock();
        }
        return "ok";
    }
}
